package com.eryos.android.cigarettecounter.database;

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.List;
import java.util.Map;
import java.util.TreeMap;

import android.database.Cursor;
import android.util.Log;

import com.eryos.android.cigarettecounter.beans.SmokeAverage;
import com.eryos.android.cigarettecounter.beans.SmokeCounter;

/**
 * Project : CigaretteCounter Author : Olivier Combe URL : http://eryos.fr/CigaretteCounter/
 * 
 * Copyright(C)2011 - Olivier Combe
 * 
 * Licensed under the Apache License, Version 2.0(the "License"); you may not use this file except in compliance with
 * the License. You may obtain a copy of the License at
 * 
 * http://www.apache.org/licenses/LICENSE-2.0
 * 
 * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on
 * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the
 * specific language governing permissions and limitations under the License.
 * 
 * @version \$Revision.*\$
 * @author Olivier Combe
 */
public final class DBTools {

    private static final String LOG_TAG = "DBTools";

    /** Number of period to display in historical views. */
    public static final int NUMBER_OF_HISTORY = 6;
    /** Number of digit for rounding. */
    public static final int ROUNDING = 2;

    /** Date format. */
    public static final String DATE_FORMAT = "%d/%m/%Y";
    /** Week format. */
    public static final String WEEK_FORMAT = "%W";
    /** Month format. */
    public static final String MONTH_FORMAT = "%m";

    /**
     * @return SQLLite sysdate
     */
    public static String getNow() {
        return "datetime(" + System.currentTimeMillis() / 1000 + ", 'unixepoch', 'localtime')";
    }

    /**
     * Private/Hidden constructor for utility class.
     */
    private DBTools() {
    }

    /*****************************************************************************/

    /**
     * @param sumArg
     *            used for average
     * @param nbArg
     *            used for average
     * @return the result of the division between SUM and NB.
     */
    public static double getAverage(final double sumArg, final double nbArg) {

        try {
            if (nbArg != 0) {
                BigDecimal sum = new BigDecimal(sumArg).setScale(2);
                BigDecimal nb = new BigDecimal(nbArg).setScale(2);

                return sum.divide(nb, DBTools.ROUNDING, RoundingMode.DOWN).doubleValue();
            } else {
                return 0;
            }
        } catch (Exception e) {
            Log.e(LOG_TAG, "Compute Average", e);
            return -1;
        }
    }

    /**
     * Parse an SQL cursor into a ArrayList of SmokeAverage(Label/Double).
     * 
     * @param mCursor
     *            Data cursor
     * @return List collection containing SmokeAverage objects
     */
    public static List<SmokeAverage> parseCursorAsSmokeAverage(final Cursor mCursor) {

        List<SmokeAverage> res = new ArrayList<SmokeAverage>();

        if (mCursor != null) {
            mCursor.moveToFirst();
            for (int i = 0; i < mCursor.getCount(); i++) {
                res.add(new SmokeAverage(mCursor.getString(0), mCursor.getDouble(3)));
                mCursor.moveToNext();
            }
        }

        return res;
    }

    /**
     * Parse an SQL cursor into a ArrayList of SmokeCount(Label/Int).
     * 
     * @param mCursor
     *            Data cursor
     * @return List collection containing SmokeCounter objects
     */
    public static List<SmokeCounter> parseCursorAsSmokeCounter(final Cursor mCursor) {

        List<SmokeCounter> res = new ArrayList<SmokeCounter>();

        if (mCursor != null) {
            mCursor.moveToFirst();
            for (int i = 0; i < mCursor.getCount(); i++) {
                SmokeCounter smoke = new SmokeCounter(mCursor.getString(0), mCursor.getInt(1));

                try {
                    Calendar c = Calendar.getInstance();
                    c.set(Calendar.DAY_OF_MONTH, mCursor.getInt(2));
                    // c.set(Calendar.MONTH, mCursor.getInt(3));
                    c.set(Calendar.MONTH, mCursor.getInt(3) - 1);
                    c.set(Calendar.YEAR, mCursor.getInt(4));
                    smoke.setDate(c);
                } catch (Exception e) {
                    Log.e(LOG_TAG, "Parse as Smoke Counter", e);
                }

                res.add(smoke);
                mCursor.moveToNext();
            }
        }

        return res;
    }

    /**
     * Parse an SQL cursor into a ArrayList of SmokeCount(Label/Int).
     * 
     * @param mCursor
     *            Data cursor
     * @return tree collection containing SmokeCounter objects
     */
    public static Map<Integer, SmokeCounter> parseCursorAsSmokeCounterSet(final Cursor mCursor) {

        Map<Integer, SmokeCounter> res = new TreeMap<Integer, SmokeCounter>();

        if (mCursor != null) {
            mCursor.moveToFirst();
            for (int i = 0; i < mCursor.getCount(); i++) {
                SmokeCounter smoke = new SmokeCounter(mCursor.getString(0), mCursor.getInt(1));

                int dayOfMonth = -1;
                try {
                    Calendar c = Calendar.getInstance();
                    dayOfMonth = mCursor.getInt(2);

                    c.set(Calendar.DAY_OF_MONTH, dayOfMonth);
                    c.set(Calendar.MONTH, mCursor.getInt(3) - 1);
                    c.set(Calendar.YEAR, mCursor.getInt(4));

                    if (mCursor.getInt(2) <= 0 || mCursor.getInt(3) <= 0 || mCursor.getInt(4) <= 0) {
                        // 29/02/2011
                        // 0123456789
                        String curDate = mCursor.getString(0);
                        c.set(Calendar.DAY_OF_MONTH, Integer.parseInt(curDate.substring(0, 2)));
                        c.set(Calendar.MONTH, Integer.parseInt(curDate.substring(3, 5)) - 1);
                        c.set(Calendar.YEAR, Integer.parseInt(curDate.substring(6)));
                    }
                    smoke.setDate(c);
                } catch (Exception e) {
                    Log.e(LOG_TAG, "Parse as Smoke Counter", e);
                }

                res.put(dayOfMonth, smoke);
                mCursor.moveToNext();
            }
        }

        return res;
    }

    /**
     * Get first result as Int.
     * 
     * @param mCursor
     *            containing results
     * @return int containing fist value
     */
    public static int getFirstIntResult(final Cursor mCursor) {
        int res = -1;
        if (mCursor != null) {
            mCursor.moveToFirst();
            res = mCursor.getInt(0);
        }

        return res;
    }

    /**
     * Get first result as Double.
     * 
     * @param mCursor
     *            containing results
     * @return double containing fist value
     */
    public static double getFirstDoubleResult(final Cursor mCursor) {
        double res = -1;
        if (mCursor != null) {
            mCursor.moveToFirst();
            res = mCursor.getDouble(0);
        }

        return res;
    }

}
